package 算法模板;

import java.util.Arrays;

/**
 * 我们将数组中的数据分为两个区间，已排序区间和未排序区间。初始已排
 * 序区间只有一个元素，就是数组的第一个元素。插入算法的核心思想是取
 * 未排序区间中的元素，在已排序区间中找到合适的插入位置将其插入，并
 * 保证已排序区间数据一直有序。重复这个过程，直到未排序区间中元素为
 * 空，算法结束。
 * <p>
 * 与冒泡排序对比：
 * <p>
 * 在冒泡排序中，经过每一轮的排序处理后，数组后端的数是排好序的。
 * 在插入排序中，经过每一轮的排序处理后，数组前端的数是排好序的。
 * <p>
 * 来源：https://github.com/doocs/leetcode/blob/main/basic/sorting/InsertionSort/README.md
 * <p>
 * 相当于打扑克牌，一张一张插入相应的位置
 */
public class 插入排序 {

    public static void main(String[] args) {

        int[] nums = {2, 5, 2, 6, 3, 5, 343, 65, 2, 1, 0, -1};
        insertSort(nums);
        System.out.println(Arrays.toString(nums));

    }

    public static void insertSort(int[] nums) {
        for (int i = 1; i < nums.length; i++) {
            //保存要插入的元素
            int readyInsertNum = nums[i];
            //准备向后移一位的元素
            int readyReplaceNum;
            //升序排序，比准备要插入的元素大的元素全部向后移一位
            for (readyReplaceNum = i - 1; readyReplaceNum >= 0 && readyInsertNum < nums[readyReplaceNum]; readyReplaceNum--) {
                nums[readyReplaceNum + 1] = nums[readyReplaceNum];
            }
            //将空出来的位置插入准备插入的值，这里j+1是因为，当for循环条件
            nums[readyReplaceNum + 1] = readyInsertNum;
        }
    }

}
